package java8;

import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.Month;
import java.time.Year;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.time.temporal.TemporalAdjusters;

public class DateTimeSample {

    public static void main(String[] args) {
        LocalDate localDate;
        LocalTime localTime;
        LocalDateTime localDateTime;
        String localDateStr, localTimeStr, localDateTimeStr;
        // ===========================================================
        // 1. 创建日期时间
        // ===========================================================
        // ---------------------------------
        // 1.1 now 当前的日期时间
        // ---------------------------------
        // ==> 2022-10-30
        localDate = LocalDate.now();
        // ==> 16:36:59.077
        localTime = LocalTime.now();
        // ==> 2022-10-30T16:36:59.077
        localDateTime = LocalDateTime.now();
        // ---------------------------------
        // 1.2 of 指定日期时间
        // ---------------------------------
        // ==> 2022-10-30
        localDate = LocalDate.of(2022, Month.OCTOBER, 30);
        // ==> 16:43:52
        localTime = LocalTime.of(16, 43, 52);
        // ==> 2022-10-30T16:43:52
        localDateTime = LocalDateTime.of(localDate, localTime);
        localDateTime = LocalDateTime.of(2022, Month.OCTOBER, 30, 16, 43, 52);
        // ---------------------------------
        // 1.3 parse 解析为日期时间
        // ---------------------------------
        // ==> LocalDate.parse 默认解析 uuuu-MM-dd 的日期格式
        localDate = LocalDate.parse("2022-10-30");
        // ==> LocalTime.parse 默认解析 HH:mm 或 HH:mm:ss 的时间格式
        localTime = LocalTime.parse("16:43:52");
        // ==> LocalDateTime.parse 默认解析 uuuu-MM-ddTHH:mm:ss[.SSS] 的日期时间格式
        localDateTime = LocalDateTime.parse("2022-10-30T16:43:52");
        // ==> 使用指定的格式
        localDate = LocalDate.parse("20221030", DateTimeFormatter.BASIC_ISO_DATE);
        localDateTime = LocalDateTime.parse("2022-10-30 16:43:52", DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss"));
        // ===========================================================
        // 2. java.util.Date/java.sql.Date 与 LocalDate/LocalTime/LocalDateTime 转换
        // ===========================================================
        // ---------------------------------
        // 2.1 java.util.Date 转 LocalDate/LocalTime/LocalDateTime
        // ---------------------------------
        // ==> Sun Oct 30 17:41:26 CST 2022
        java.util.Date utilDate = new java.util.Date(System.currentTimeMillis());
        // ==> Instant是java8新增的时间戳类, Instant.now() 可以获取当前时间戳, 和 System.currentTimeMillis() 效果相似
        // ==> Instant 加上具体的时区 ZoneId, 可以得到带时区的日期时间 ZonedDateTime
        // ==> ZonedDateTime 可以转对应的日期或时间 LocalDate/LocalTime/LocalDateTime
        // ==> 2022-10-30
        localDate = utilDate.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
        // ==> 18:33:26.599
        localTime = utilDate.toInstant().atZone(ZoneId.systemDefault()).toLocalTime();
        // ==> 2022-10-30T18:33:26.599
        localDateTime = utilDate.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
        // ---------------------------------
        // 2.2 LocalDate/LocalDateTime 转 java.util.Date
        // ---------------------------------
        utilDate = java.util.Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
        utilDate = java.util.Date.from(localDate.atStartOfDay(ZoneId.systemDefault()).toInstant());
        // ---------------------------------
        // 2.3 java.sql.Date 转 LocalDate/LocalTime/LocalDateTime
        // ---------------------------------
        // ==> java.sql.Date 是只有日期没有时间的, 这是和 java.util.Date 的区别
        java.sql.Date sqlDate = new java.sql.Date(System.currentTimeMillis());
        // ==> 2022-10-30
        localDate = sqlDate.toLocalDate();
        // ===========================================================
        // 3. 格式化
        // ===========================================================
        // ---------------------------------
        // 3.1 toString 默认的格式化模式
        // ---------------------------------
        // ==> uuuu-MM-dd
        localDateStr = localDate.toString();
        // ==> HH:mm:ss.SSS
        localTimeStr = localTime.toString();
        // ==> uuuu-MM-ddTHH:mm:ss.SSS
        localDateTimeStr = localDateTime.toString();
        // ---------------------------------
        // 3.2 指定格式模式串
        // ---------------------------------
        // ==> uuuu-MM-dd 格式
        localDateStr = localDate.format(DateTimeFormatter.ISO_LOCAL_DATE);
        // ==> HH:mm:ss.SSS 格式
        localTimeStr = localTime.format(DateTimeFormatter.ISO_LOCAL_TIME);
        // ==> uuuu-MM-ddTHH:mm:ss.SSS 格式
        localDateTimeStr = localDateTime.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME);
        // ==> 自己指定格式模式串
        localDateTimeStr = localDateTime.format(DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss"));
        // ===========================================================
        // 4. 获取值
        // ===========================================================
        // ---------------------------------
        // 4.1 取值
        // ---------------------------------
        // ==> 年 2022
        int year = localDateTime.getYear();
        // ==> 月 OCTOBER
        Month month = localDateTime.getMonth();
        // ==> 月 10
        int monthValue = localDateTime.getMonthValue();
        // ==> 日 31
        int day = localDateTime.getDayOfMonth();
        // ==> 时 9
        int hour = localDateTime.getHour();
        // ==> 分 9
        int minute = localDateTime.getMinute();
        // ==> 秒 5
        int second = localDateTime.getSecond();
        // ==> 星期几 SUNDAY
        DayOfWeek dayOfWeek = localDateTime.getDayOfWeek();
        // ==> 一年的第几天 310
        int dayOfYear = localDateTime.getDayOfYear();
        // ===========================================================
        // 5. 日期时间比较
        // ===========================================================
        // ---------------------------------
        // 5.1 时间差计算
        // ---------------------------------
        LocalDateTime datetime1 = LocalDateTime.parse("2022-01-01T00:00:00");
        LocalDateTime datetime2 = LocalDateTime.parse("2023-12-31T23:59:59");
        // ==> datetime1 距离 datetime2 的时间差值 23
        long months = datetime1.until(datetime2, ChronoUnit.MONTHS);
        // ==> datetime1 距离 datetime2 的时间差值 729
        long days = datetime1.until(datetime2, ChronoUnit.DAYS);
        // ---------------------------------
        // 5.2 加计算
        // ---------------------------------
        LocalDateTime datetimePlus = LocalDateTime.parse("2022-01-01T00:00:00");
        // ==> 2023-02-02T01:01:01
        datetimePlus = datetimePlus
                .plusYears(1)
                .plusMonths(1)
                .plusDays(1)
                .plusHours(1)
                .plusMinutes(1)
                .plusSeconds(1);
        // ---------------------------------
        // 5.3 减计算
        // ---------------------------------
        LocalDateTime datetimeMinus = LocalDateTime.parse("2022-01-01T00:00:00");
        // ==> 2020-11-29T22:58:59
        datetimeMinus = datetimeMinus
                .minusYears(1)
                .minusMonths(1)
                .minusDays(1)
                .minusHours(1)
                .minusMinutes(1)
                .minusSeconds(1);
        // ===========================================================
        // 6. 其它
        // ===========================================================
        LocalDateTime datetime = LocalDateTime.parse("2022-01-10T23:59:59");
        // ==> 月的第一天 2022-01-01T23:59:59
        LocalDateTime firstDayOfMonth = datetime.with(TemporalAdjusters.firstDayOfMonth());
        // ==> 月的最后一天 2022-01-31T23:59:59
        LocalDateTime lastDayOfMonth = datetime.with(TemporalAdjusters.lastDayOfMonth());
        // ==> 是否闰年 false
        boolean leap = Year.isLeap(2022);
    }

}